package com.hx.netty.chat.server;

import com.hx.netty.chat.protocol.ImDecoder;
import com.hx.netty.chat.protocol.ImEncoder;
import com.hx.netty.chat.server.handler.HttpServerHandler;
import com.hx.netty.chat.server.handler.TerminalServerHandler;
import com.hx.netty.chat.server.handler.WebSocketServerHandler;
import com.sun.net.httpserver.HttpServer;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.stream.ChunkedWriteHandler;

/**
 * @author Huathy
 * @date 2021-10-28 21:58
 * @description
 */
public class ChatServer {
    private int port = 8888;

    public void start(int port) {
        // 主从线程模型的线程池
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_BACKLOG, 1024)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ChannelPipeline pipeline = ch.pipeline();
                            /* 解析自定义协议 */
                            pipeline.addLast(new ImDecoder());     // Inbound
                            pipeline.addLast(new ImEncoder());      // Outbound
                            // 专门用来处理直接发送Immessage对象的IDE控制台
                            pipeline.addLast(new TerminalServerHandler());  // Inbound

                            /* 解析http请求 */
                            pipeline.addLast(new HttpServerCodec());    //outboud
                            // 主要是将同一个http请求或相应的多个消息编程一个fullHttpRequest完成的消息对象
                            pipeline.addLast(new HttpObjectAggregator(64 * 1024));      //inbound
                            //主要用来处理大数据流，比如1G大小的文件，如果直接传输肯定会撑爆jvm内存，加上这个handler
                            pipeline.addLast(new ChunkedWriteHandler());  //inbound outbound
                            // 处理web页面，解析http协议
                            pipeline.addLast(new HttpServerHandler());  //inbound

                            /* 解析websocket请求 */
                            pipeline.addLast(new WebSocketServerProtocolHandler("/im"));
                            //用来处理websocket通信协议   IM实时聊天
                            pipeline.addLast(new WebSocketServerHandler()); //inbound


                        }
                    });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
